#include<stdio.h>
#include<stdlib.h>
#include "DoubleLinkList.h"

int InitDLlist(DLlist *list)
{
    list->head=NULL;
    list->tail=NULL;
    list->len=0;
    return 0;
}

struct Node * CreateNode(ElementType element)
{
    struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));
    if(newNode==NULL)
    {
        printf("CreateNode malloc error!\n");
        return NULL;
    }

    newNode->next=NULL;
    newNode->prev=NULL;
    newNode->data=element;
    return newNode;
}

void InsertTail(DLlist *list, ElementType element)
{
    struct Node *newNode=CreateNode(element);
    if(newNode==NULL)
    {
        printf("InserTail create error");
        return;
    }
    if(list->len==0)
    {
        list->head=newNode;
        list->tail=newNode;
    }
    else
    {
    list->tail->next=newNode;
    newNode->prev=list->tail;
    list->tail=newNode;
    }
    list->len++;
}

void InsertHead(DLlist *list, ElementType element)
{
    struct Node *newNode=CreateNode(element);
    if(newNode==NULL)
    {
        printf("InserTail create error");
        return;
    }
    if(list->len==0)
    {
        list->head=newNode;
        list->tail=newNode;
    }
    else
    {
        list->head->prev=newNode;
        newNode->next=list->head;
        list->head=newNode;
    }
    list->len++;
}

void RemoveByIndex(DLlist *list, int index)
{
    if(index<0||index>=list->len)
    {
        printf("Remove invaild place!\n");
        return;
    }
    if(index==0)
    {
        if(list->len==1)
        {
            free(list->head);
            list->head=NULL;
            list->tail=NULL;
            list->len=0;
            return;
        }
        struct Node*freeNode=list->head;
        list->head=list->head->next;
        list->head->prev=NULL;
        free(freeNode);
        list->len--;
        return;
    }
    if(index==list->len-1)
    {
        struct Node*freeNode=list->tail;
        list->tail=list->tail->prev;
        list->tail->next=NULL;
        free(freeNode);
        list->len--;
        return;
    }
struct Node*TravelPoint=list->head;
while(index>0)
{
    TravelPoint=TravelPoint->next;
    index--;
}

    struct Node *PrevNode=TravelPoint->prev;
    struct Node *NextNode=TravelPoint->next;
    PrevNode->next=TravelPoint->next;
    NextNode->prev=TravelPoint->prev;
    free(TravelPoint);
    list->len--; 
}

void RemoveByelement(DLlist *list, ElementType element)
{
   int index=FindFirstByElement(list,element);
   while(index!=-1)
   {
    RemoveByIndex(list,index);
    index=FindFirstByElement(list,element);
   }
}

int FindFirstByElement(DLlist *list, ElementType element)
{
    int count=0;
    struct Node*TravelPoint=list->head;
    while(TravelPoint!=NULL)
    {
        if(TravelPoint->data==element)
        {
            return count;
        }
        count++;
        TravelPoint=TravelPoint->next;
    }
    return -1;
}

int GetListLen(DLlist *list)
{
    return list->len;
}

void Travel1(DLlist *list, void (*func)(ElementType))
{
    struct Node*TravelPoint=list->head;
    // printf("len : %d\n",list->len);
    // printf("next :");
    while(TravelPoint!=NULL)
    {
        if(func!=NULL)
        {
            func(TravelPoint->data);
        }
        // printf("%d ",TravelPoint->data);
        TravelPoint=TravelPoint->next;
    }
    // printf("\n");

    // printf("prev :");
    // TravelPoint=list->tail;
    // while(TravelPoint!=NULL)
    // {
    //     printf("%d ",TravelPoint->data);
    //     TravelPoint=TravelPoint->prev;
    // }
    // printf("\n");

}

void FreeDLlist(DLlist *list)
{
    while(list->head!=NULL)
    {
        struct Node *freeNode=list->head;
        list->head=list->head->next;
        // func(freeNode->data);
        free(freeNode);
    }
    list->head=NULL;
    list->tail=NULL;
    list->len=0;
}
